

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Locale;

import javax.swing.JFileChooser;
import javax.swing.UIManager;
import javax.swing.UIManager.LookAndFeelInfo;

import org.ini4j.Ini;
import org.ini4j.InvalidFileFormatException;

import uk.co.caprica.vlcj.binding.LibVlc;
import uk.co.caprica.vlcj.runtime.RuntimeUtil;
import variables.VarConfigInt;
import variables.VarErreurInt;
import variables.VarSystemInt;
import views.FenetreNewError;
import views.FenetrePrincipale;

import com.sun.jna.Native;
import com.sun.jna.NativeLibrary;

/**
 * Classe principale
 * @author CHA J�r�me et YANG Pahoua
 *
 */
public class BancVLC {

	protected Ini ini;
	protected JFileChooser myFileChooser = new JFileChooser();
	protected File ourPath, libvlc, libvlccore;
	protected boolean isDefined = false;
	
	public BancVLC (){
		
		// Creation du .ini lors de la premiere utilisation
		File configFile = new File(VarConfigInt.CONFIG_FILENAME);
		if(!configFile.exists()){
			createIni(configFile);
		}
		
		// Recuperation du fichier .ini
		try{
			ini = new Ini(new File(VarConfigInt.CONFIG_FILENAME));
		} catch (InvalidFileFormatException e) {
			new FenetreNewError(VarErreurInt.ERREUR_CONFIG_INVALIDE_FORMAT);
		} catch (IOException e) {
			new FenetreNewError(VarErreurInt.ERREUR_CONFIG_INVALIDE_TYPE);
		}
		
		// look and feel
		try {
		    for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
		        if ("Nimbus".equals(info.getName())) {
		            UIManager.setLookAndFeel(info.getClassName());
		            break;
		        }
		    }
		} catch (Exception e) {
		    // If Nimbus is not available, you can set the GUI to another look and feel.
		}
		
		// initialisation des liens vers les repertoires dans le fichier config.ini
		Ini.Section paths = ini.get(VarConfigInt.CONFIG_SECTION_PATH);
		
		// Sauvegarde du repertoire vlc
		if(paths.get(VarConfigInt.CONFIG_VAR_PATH_VLC).equalsIgnoreCase(VarConfigInt.CONFIG_BASIC_VALUE)){
			
			while(!isDefined){
				String osName = VarSystemInt.SYS_PROP_OSNAME;
				boolean is_mac = osName.indexOf(VarSystemInt.SYS_OSNAME_MAC) >= 0;
				boolean is_windows = osName.indexOf(VarSystemInt.SYS_OSNAME_WIN) >= 0;
				
				// Si c'est un mac on n'ouvre pas la fenetre d'ouverture
				if (is_mac) {
					// On test que les fichiers sont bien pr�sents
					this.libvlc = new File(VarSystemInt.SYS_VLC_PATH_MAC + VarSystemInt.SYS_PROP_FILESEPARATOR+ VarSystemInt.SYS_VLC_LIB + VarSystemInt.SYS_EXT_MAC);
					this.libvlccore = new File(VarSystemInt.SYS_VLC_PATH_MAC + VarSystemInt.SYS_PROP_FILESEPARATOR+ VarSystemInt.SYS_VLC_LIB_CORE + VarSystemInt.SYS_EXT_MAC);
					
					isDefined = checkPath(VarSystemInt.SYS_VLC_PATH_MAC);
				} else {
					// on demande � l'utilisateur d'aller chercher le r�pertoire de vlc
					this.myFileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
					int returnVal = this.myFileChooser.showOpenDialog(null);
					this.ourPath = this.myFileChooser.getSelectedFile(); 
				
					 if(returnVal == JFileChooser.CANCEL_OPTION) {
						 System.exit(0);
					 }
					
					// On test si le dossier est bien celui de vlc
					if(is_windows){
						this.libvlc = new File(this.ourPath + VarSystemInt.SYS_PROP_FILESEPARATOR+ VarSystemInt.SYS_VLC_LIB + VarSystemInt.SYS_EXT_WiN);
						this.libvlccore = new File(this.ourPath + VarSystemInt.SYS_PROP_FILESEPARATOR+ VarSystemInt.SYS_VLC_LIB_CORE + VarSystemInt.SYS_EXT_WiN);
					} else{
						this.libvlc = new File(this.ourPath + VarSystemInt.SYS_PROP_FILESEPARATOR+ VarSystemInt.SYS_VLC_LIB + VarSystemInt.SYS_EXT_LINUX);
						this.libvlccore = new File(this.ourPath + VarSystemInt.SYS_PROP_FILESEPARATOR+ VarSystemInt.SYS_VLC_LIB_CORE + VarSystemInt.SYS_EXT_LINUX);
						System.out.println(this.ourPath + VarSystemInt.SYS_PROP_FILESEPARATOR+ VarSystemInt.SYS_VLC_LIB + VarSystemInt.SYS_EXT_LINUX);
						System.out.println(this.ourPath + VarSystemInt.SYS_PROP_FILESEPARATOR+ VarSystemInt.SYS_VLC_LIB_CORE + VarSystemInt.SYS_EXT_LINUX);
					}
					
					isDefined = checkPath(this.ourPath.getAbsolutePath());
				}
			}
		}
		
		NativeLibrary.addSearchPath(RuntimeUtil.getLibVlcLibraryName(), paths.get(VarConfigInt.CONFIG_VAR_PATH_VLC));
		Native.loadLibrary(RuntimeUtil.getLibVlcLibraryName(), LibVlc.class);
		
		new FenetrePrincipale(ini);
	}
	
	/**
	 * creation du .ini lors du premier lancement
	 */
	@SuppressWarnings("resource")
	private void createIni(File configFile){
		try {
			//creation du fichier ini
			new FileOutputStream(configFile);
			Ini configIni = new Ini(configFile);
			//insertion de la configuration des diférents path
			configIni.put(VarConfigInt.CONFIG_SECTION_PATH, VarConfigInt.CONFIG_VAR_PATH_VLC, VarConfigInt.CONFIG_BASIC_VALUE);
			configIni.put(VarConfigInt.CONFIG_SECTION_PATH, VarConfigInt.CONFIG_VAR_PATH_SRC, VarConfigInt.CONFIG_BASIC_VALUE);
			String osName = VarSystemInt.SYS_PROP_OSNAME;
			String absolutePath;
			boolean is_mac = osName.indexOf(VarSystemInt.SYS_OSNAME_MAC) >= 0;
			boolean is_windows = osName.indexOf(VarSystemInt.SYS_OSNAME_WIN) >= 0;
			if(is_mac){
				configIni.put(VarConfigInt.CONFIG_SECTION_SOFTWARE, VarConfigInt.CONFIG_VAR_SOFTWARE_FFMPEG, VarConfigInt.CONFIG_FFMPEG_MAC);
				absolutePath = VarSystemInt.SYS_PROP_USERHOME + VarSystemInt.SYS_PROP_FILESEPARATOR + VarSystemInt.SYS_FOLDER_MOVIES + VarSystemInt.SYS_PROP_FILESEPARATOR;
			} else {
				if (is_windows) {
					configIni.put(VarConfigInt.CONFIG_SECTION_SOFTWARE, VarConfigInt.CONFIG_VAR_SOFTWARE_FFMPEG, VarConfigInt.CONFIG_FFMPEG_WINDOWS);
				} else {
					configIni.put(VarConfigInt.CONFIG_SECTION_SOFTWARE, VarConfigInt.CONFIG_VAR_SOFTWARE_FFMPEG, VarConfigInt.CONFIG_FFMPEG_LINUX);
				}
				absolutePath = VarSystemInt.SYS_PROP_USERHOME + VarSystemInt.SYS_PROP_FILESEPARATOR + VarSystemInt.SYS_FOLDER_VIDEOS + VarSystemInt.SYS_PROP_FILESEPARATOR;
			}
			
			if(!new File(absolutePath).exists()){
				absolutePath = VarSystemInt.SYS_PROP_USERHOME + VarSystemInt.SYS_PROP_FILESEPARATOR;
			}
			configIni.put(VarConfigInt.CONFIG_SECTION_PATH, VarConfigInt.CONFIG_VAR_PATH_MOVIES, absolutePath);
			configIni.put(VarConfigInt.CONFIG_SECTION_PATH, VarConfigInt.CONFIG_VAR_PATH_DEST, absolutePath + VarConfigInt.CONFIG_BASIC_FOLDER + VarSystemInt.SYS_PROP_FILESEPARATOR);
			//insertion de la configuration de la langue
			Locale locale = Locale.getDefault();
			configIni.put(VarConfigInt.CONFIG_SECTION_LOCALE, VarConfigInt.CONFIG_VAR_LOCALE_LANG, locale.getLanguage());
			//insertion de size
			configIni.put(VarConfigInt.CONFIG_SECTION_SIZE, VarConfigInt.CONFIG_VAR_SIZE_HEIGHT, VarConfigInt.CONFIG_BASIC_HEIGHT);
			configIni.put(VarConfigInt.CONFIG_SECTION_SIZE, VarConfigInt.CONFIG_VAR_SIZE_WIDTH, VarConfigInt.CONFIG_BASIC_WIDTH);
			//ecriture et sauvegarde du fichier ini
			configIni.store();
		} catch (FileNotFoundException e) {
			new FenetreNewError(VarErreurInt.ERREUR_CONFIG_INVALIDE_FILE);
		} catch (InvalidFileFormatException e) {
			new FenetreNewError(VarErreurInt.ERREUR_CONFIG_INVALIDE_FORMAT);
		} catch (IOException e) {
			new FenetreNewError(VarErreurInt.ERREUR_CONFIG_INVALIDE_TYPE);
		}
	}
	
	/**
	 * Test si les librairie vlc et vlccore sont bien presentes
	 * Et si c'est correct on enregistre le r�pertoire dans le .ini
	 */
	public boolean checkPath(String path){
		
		// on test si les librairies sont pr�sentes
		if (!(this.libvlc.exists() && libvlccore.exists())){
			new FenetreNewError(VarErreurInt.ERREUR_VLC_LIB);
			return false;
		}
		// une fois que c'est fait on la sauvegarde dans le .ini
		this.ini.put(VarConfigInt.CONFIG_SECTION_PATH,VarConfigInt.CONFIG_VAR_PATH_VLC,path);
		try {
			this.ini.store();
		} catch (IOException e) {
			new FenetreNewError(VarErreurInt.ERREUR_INI_SAVE);
			return false;
		}
		return true;
	}
	
	public static void main(String[] args) {
		new BancVLC();
	}
}
